////////////////////////////////////////////////////////////////////////////////
// This file is part of the Mist compiler.                                    //
//                                                                            //
// Copyright (C) 2008, 2009 The Mist project                                  //
//                                                                            //
// For a list of contributors, see the COMMITTERS file.                       //
//                                                                            //
// The Mist compiler is free software: you can redistribute it and/or modify  //
// it under the terms of the GNU General Public License as published by       //
// the Free Software Foundation, either version 3 of the License, or          //
// (at your option) any later version.                                        //
//                                                                            //
// The Mist compiler is distributed in the hope that it will be useful,       //
// but WITHOUT ANY WARRANTY; without even the implied warranty of             //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              //
// GNU General Public License for more details.                               //
//                                                                            //
// You should have received a copy of the GNU General Public License          //
// in the COPYING file. If not, see <http://www.gnu.org/licenses/>.           //
////////////////////////////////////////////////////////////////////////////////

///
/// \file
/// Contains the implementation of the Location member functions.
///

#include "location.hpp"

////////////////////////////////////////////////////////////////////////////////
// Includes                                                                   //
////////////////////////////////////////////////////////////////////////////////

#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
using boost::make_tuple;

#include "location.hh"

////////////////////////////////////////////////////////////////////////////////
// Function Implementations                                                   //
////////////////////////////////////////////////////////////////////////////////

Location::Location(const yy::location& l) : begin(l.begin), end(Position(l.end).predecessor()) {
} // intentionally empty

Location::Location(const Position& b, const Position& e) : begin(b), end(e) {
	assert(b.file == e.file);
}

Location::Location(const Location& b, const Location& e) : begin(b.begin), end(e.end) {
	assert(b.begin.file == e.end.file);
} // intentionally empty

Location::Location(string file, uint beginLine, uint beginColumn, uint endLine, uint endColumn) : begin(file, beginLine, beginColumn), end(file, endLine, endColumn) {
} // intentionally empty

Location::Location(string file, uint line, uint beginColumn, uint endColumn) : begin(file, line, beginColumn), end(file, line, endColumn) {
} // intentionally empty

Location::Location(string file, uint line, uint column) : begin(file, line, column), end(file, line, column) {
} // intentionally empty

bool Location::is_in(const Location& other) const {
	return begin.file == other.begin.file
	    && begin      >= other.begin
	    && end        <= other.end;
}

ostream& Location::send_to_stream(ostream& out) const {
	if (begin.file == end.file) {
		out << begin.file << ":";
		if (begin.line == end.line) {
			out << begin.line;
			if (begin.column == end.column)
				out << ":"  << begin.column;
			else
				out << ": " << begin.column << "-" << end.column;
		} else {
			out << " ";
			out << begin.line << ":" << begin.column << "-"
			    <<   end.line << ":" <<   end.column;
		}
	} else {
		out << begin << "-" << end;
	}
	
	return out;
}

bool Location::operator<(const Location& other) const {
	return make_tuple(begin, end) < make_tuple(other.begin, other.end);
}
